<script setup lang="ts">
import type { TemplateUIType } from '@/types/custom'
import type { VxeGridConstructor, VxeGridDefines, VxeGridProps } from 'vxe-table'
import { onBeforeMount, reactive, ref, unref, watch } from 'vue'
import { useBaseApi } from '@/api/base'
import { storeToRefs } from 'pinia'
import { useAppState } from '@/stores/appState'
import {
  columnFilterMethod,
  formatColRows,
  initFooterMethod,
  initFormatColumns,
  initGridProps,
  removeGridColumns,
  setGridColumns
} from '@/views/components/grid/libs'
import { ArrowDown, ArrowUp, Checked, Delete } from '@element-plus/icons-vue'
import { isArray, isNumber } from 'xe-utils'
import TemplateGridSelector from '@/views/components/grid/components/TemplateGridSelector.vue'
import { Local } from '@/utils/storage'

interface Props {
  business_id?: string
  disabled?: boolean
  multiple?: boolean
  title?: string
  field?: string
}

const modelValue = defineModel<string | string[] | undefined>()
const props = defineProps<Props>()
const emit = defineEmits(['change', 'fetch'])

const count = ref(0)
const loading = ref(false)
const selectorRef = ref()
const business = ref<TemplateUIType | undefined>()
const gridOptions = ref<VxeGridProps<TypedAny>>({})
const gridData = ref<TypedAny[]>([])
const showKey = `${props.field}_selector_show`
const isShow = ref(Local.get(showKey) || false)
// 表格分页
const gridPage = reactive({
  total: 0,
  page: 1,
  pageSize: 50
})

const { CustomRequest, get_business_ui } = useBaseApi()
const { mobile } = storeToRefs(useAppState())

const onFetchBusiness = async () => {
  if (!props.business_id) return Promise.reject('没有业务ID')
  const { data } = await get_business_ui(props.business_id)
  business.value = data
  if (data.ui_table) {
    // 格式化表格配置
    gridOptions.value = initGridProps({
      uiTable: data.ui_table,
      radioConfig: {
        trigger: 'row',
        reserve: true,
        highlight: true
      }
    })

    const cols = await initFormatColumns({
      uiForm: data.ui_form,
      uiTable: data.ui_table,
      dicTable: data.dic_table,
      uiActions: data.actions
    })

    // 初始化表尾合计
    initFooterMethod(unref(gridOptions), cols)

    gridOptions.value.columns = cols.filter((f) => f.field !== 'action')
  }

  await onFetch()

  loading.value = false
}

const onFetch = async () => {
  const ui = unref(business)
  if (ui) {
    const api = ui.ui_table?.api
    const method = ui.ui_table?.method || 'post'
    const keyField = ui.ui_table?.default_value_parse.keyField || 'id'
    const value = unref(modelValue)
    const ids = isArray(value) ? value : value ? [value] : []
    if (!ids.length) return
    const { data } = await CustomRequest({
      url: api,
      method: method || 'post',
      params: method === 'get' ? { [keyField]: ids } : {},
      data: method === 'post' ? { [keyField]: ids } : {}
    })

    // 总数
    if (data && isNumber(data.total)) gridPage.total = data.total

    let list: TypedAny[] = []
    if (isArray(data)) {
      list = data
    } else if (data.items) {
      list = data.items
    }

    formatColRows({
      rows: list,
      uiTable: ui.ui_table,
      uiForm: ui.ui_form,
      dicTable: ui.dic_table
    })

    gridData.value = list
  }
}

const setCustomColumns = ($grid: VxeGridConstructor) => {
  if (business.value?.ui_table) {
    const { fullColumn } = $grid.getTableColumn()
    const cols = fullColumn
      .filter((column) => columnFilterMethod({ column }))
      .map((v, seq) => {
        return {
          type: v.type,
          field: v.field,
          fixed: v.fixed,
          visible: v.visible,
          width: v.renderWidth,
          seq
        }
      })
    setGridColumns(business.value?.ui_table, cols)
  }
}

const onCustomChange = ({ $grid, type }: VxeGridDefines.CustomEventParams) => {
  if (business.value?.ui_table) {
    if (type === 'reset') {
      removeGridColumns(business.value?.ui_table)
      onFetch()
    } else if (type === 'confirm') {
      setCustomColumns($grid)
    }
  }
}

const onResizableChange = ({ $grid }: VxeGridDefines.ResizableChangeEventParams) => {
  if (business.value?.ui_table) {
    setCustomColumns($grid)
  }
}

const onActionOpenSelector = () => {
  selectorRef.value.open()
}

const handleSelectorConfirm = (value: string | string[]) => {
  modelValue.value = value
  if (props.multiple) {
    if (!value.length) handleClear()
  } else if (!value) {
    handleClear()
  }
}

const handleShow = () => {
  isShow.value = !isShow.value
  Local.set(showKey, isShow.value)
}

const handleClear = () => {
  modelValue.value = props.multiple ? [] : undefined
  gridData.value = []
  gridPage.total = 0
  selectorRef.value?.handleClear()
}

watch(
  modelValue,
  (value) => {
    count.value = isArray(value) ? value.length : value ? 1 : 0
    onFetch()
    emit('fetch')
  },
  { deep: true }
)

onBeforeMount(() => {
  onFetchBusiness()
})
</script>

<template>
  <div class="h100">
    <el-space :size="5">
      <el-button
        plain
        :icon="Checked"
        :type="count ? 'primary' : 'default'"
        @click="onActionOpenSelector()"
      >
        {{ title }}（{{ count }}）
      </el-button>
      <el-button plain :icon="Delete" @click="handleClear">清空</el-button>
      <el-button plain :icon="isShow ? ArrowUp : ArrowDown" @click="handleShow">
        {{ isShow ? '隐藏详情' : '显示详情' }}
      </el-button>
    </el-space>
    <vxe-grid
      v-if="isShow"
      class="mt5"
      ref="xGrid"
      v-bind="gridOptions"
      :data="gridData"
      :loading="loading"
      :max-height="250"
      append-to-body
      header-row-class-name="base-bg-color"
      @custom="onCustomChange"
      @resizable-change="onResizableChange"
    >
      <!-- 标签 -->
      <template #el_tag="{ row, column }">
        <el-tag :type="row[`${column.field}_display_type`] || 'info'">
          {{ row[column.field] }}
        </el-tag>
      </template>
      <!-- pager 插槽-->
      <template #pager>
        <vxe-pager
          :layouts="
            mobile
              ? ['PrevJump', 'PrevPage', 'Number', 'NextPage', 'Total']
              : [
                  'Sizes',
                  'PrevJump',
                  'PrevPage',
                  'Number',
                  'NextPage',
                  'NextJump',
                  'FullJump',
                  'Total'
                ]
          "
          v-model:current-page="gridPage.page"
          v-model:page-size="gridPage.pageSize"
          :total="gridPage.total"
          @page-change="onFetch()"
        >
        </vxe-pager>
      </template>
    </vxe-grid>
    <TemplateGridSelector
      ref="selectorRef"
      v-model="modelValue"
      :business_id="props.business_id"
      :multiple="props.multiple"
      @confirm="handleSelectorConfirm"
    />
  </div>
</template>
